package com.jy.modules.cims.loan.service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import com.jy.modules.cims.common.CimsConstant;
import com.jy.modules.cims.common.exception.CimsExceptionConstant;
import com.jy.modules.cims.common.exception.InteractException;
import com.jy.modules.cims.common.sysUtils.SearchParamUtil;
import com.jy.modules.cims.component.balance.SettleUtilsService;
import com.jy.modules.cims.data.common.dao.TCMmCreditTimeoutDao;
import com.jy.modules.cims.data.common.dao.TCMmDealMatchDao;
import com.jy.modules.cims.data.common.dto.TCMmCreditDealDetailDTO;
import com.jy.modules.cims.data.common.dto.TCMmCreditTimeoutDTO;
import com.jy.modules.cims.data.common.dto.TCMmDealMatchDTO;
import com.jy.modules.cims.data.dao.CreditDealDetailDao;
import com.jy.modules.cims.data.dto.CreditDetailDto;
import com.jy.modules.cims.data.dto.credit.PublicSettleParamDto;
import com.jy.modules.cims.data.dto.credit.PublicSettleResultDto;
import com.jy.modules.cims.data.dto.loan.LoanBuybackSettleCreditDto;
import com.jy.modules.cims.data.dto.loan.LoanBuybackSettleDto;
import com.jy.modules.cims.deal.service.DealService;
import com.jy.modules.cims.deal.service.TimeoutService;
import com.jy.modules.cims.interact.ICInteract;
import com.jy.modules.cims.interact.IInteractAssist;
import com.jy.platform.api.org.SessionAPI;

/**
 * <b>类名称：</b>LoanBuybackSettleService <br/>
 * <b>类描述：贷款回购结算服务层</b><br/>
 * <b>创建人：</b>yanjingying<br/>
 * <b>修改人：</b><br/>
 * <b>修改时间：</b>2016-08-19 下午16:00:00<br/>
 * <b>修改备注：</b><br/>
 * <b>版本信息：</b>v1.0.0<br/>
 */
@Service("com.jy.modules.cims.loan.service.LoanBuybackSettleService")
public class LoanBuybackSettleService {
	private static final Logger logger = LoggerFactory.getLogger(LoanBuybackSettleService.class);
	
	@Autowired
	@Qualifier("com.jy.modules.cims.interact.CCInteractImpl")
	private ICInteract iCInteract;
	
	@Autowired
	@Qualifier("com.jy.modules.cims.deal.service.DealService")
	public DealService dealService;
	
	@Autowired
	private CreditDealDetailDao creditDealDetailDao;
	
	@Autowired
	private TCMmDealMatchDao tCMmDealMatchDao;
	
	@Autowired
	private SessionAPI sessionAPI;
	
	@Autowired
    @Qualifier("com.jy.modules.cims.component.balance.SettleUtilsService")
    private SettleUtilsService settleUtilsService;
	
	@Autowired
	@Qualifier("com.jy.modules.cims.interact.CInteractAssist")
	public IInteractAssist iInteractAssist;
	
	@Autowired
	@Qualifier("com.jy.modules.cims.deal.service.TimeoutService")
	private TimeoutService timeoutService;
	
	@Autowired
	private TCMmCreditTimeoutDao timeoutDao;
	
	/**
	 * 处理贷款回购结算(多个交易流水号)
	 * @param ids 交易流水号字符串
	 * @return
	 * @throws Exception
	 */
	public String doLoanBuybackSettleMore(String ids) throws Exception{
		StringBuffer result = new StringBuffer();
		
		//查询接口调用超时表，向核心重发超时数据
		result.append(doLoanBuybackSettleTimeOut(new String[]{"4049"}));
		
		//处理结算申请数据-正常
		result.append(doLoanBuybackSettleNormal(ids));
		
   	 	return result.toString();
	}
	
	/**
	 * 贷款回购结算申请接口调用超时重发处理
	 * @param interfaceNo 接口编号
	 * @return
	 * @throws Exception
	 */
	public String doLoanBuybackSettleTimeOut(String[] interfaceNo) throws Exception{
		StringBuffer result = new StringBuffer();
		String resultMsg = "";
		String costStatuss = CimsConstant.COST_STATUS_DJ  +","+ CimsConstant.COST_STATUS_BH;  //结算状态为01-待结算,04-已驳回
		String creditSource = "02"; //来源：02-贷款
		List<String> timeoutTransNoList = queryTimeoutTransNos(interfaceNo);
		if(CollectionUtils.isNotEmpty(timeoutTransNoList)){
			for(String timeoutTransNo : timeoutTransNoList) {
				logger.info("前端系统交易流水号=" + timeoutTransNo + "调用接口之前未处理完成，将重新调用4049接口进行处理!");
				Map<String,Object> searchParams = new HashMap<String,Object>();
				TCMmCreditTimeoutDTO param = new TCMmCreditTimeoutDTO();
				param.setFrontTransNo(timeoutTransNo);
				searchParams.put("dto", param);
				//查询timeout记录表
				List<TCMmCreditTimeoutDTO> timeoutList = timeoutDao.searchTCMmCreditTimeout(searchParams);
				for(TCMmCreditTimeoutDTO timeOutDto : timeoutList){
					String dealCode = timeOutDto.getDealCode();
					Map<String, Object>  paramNew = new HashMap<String, Object>();
					paramNew.put("dealCode", dealCode); //交易流水号
					paramNew.put("creditSource", creditSource); //来源
					paramNew.put("costStatuss", costStatuss);//结算状态为01-待结算,04-已驳回
					List<CreditDetailDto> list = dealService.getDealDetailListReturn(paramNew);
					String applyCode = settleUtilsService.autoMakeSettleApplyCode(dealCode); //根据交易流水号自动生成结算编号
					logger.info("交易流水号="+dealCode+"，自动生成结算申请编号="+applyCode);
					if(CollectionUtils.isNotEmpty(list)){
						try {
							doLoanBuybackSettleSingle(dealCode, applyCode, timeoutTransNo, list);
							resultMsg = "【重发超时】交易流水号=" + dealCode + "，结算申请编号=" + applyCode + "的结算申请处理成功!";
							result.append(resultMsg).append("\n\n");
							logger.info(resultMsg);
							
							//处理成功后，需要删除timeout记录表
							int cnt = timeoutDao.queryTimeoutCountByFrontNo(timeoutTransNo);
							if (cnt > 0) {
								logger.info("超时表记录处理完毕后,删除超时记录");
								timeoutDao.deleteTCMmCreditTimeoutByFrontNo(timeoutTransNo);
							}
						} catch (Exception e) {
							resultMsg = "【重发超时】数据异常," + e.getMessage() + "，前端流水号=" + timeoutTransNo;
							result.append(resultMsg).append("\n\n");
							logger.error(resultMsg);
						}
					}
				}
			}
		}else{
			resultMsg = "所调用的贷款回购结算申请4049接口都处理完成，超时表中无未处理数据!";
			logger.error(resultMsg);
		}
		
		return result.toString();
	}
	
	/**
	 * 贷款回购结算申请接口调用正常处理
	 * @param ids
	 * @return
	 * @throws Exception
	 */
	public String doLoanBuybackSettleNormal(String ids) throws Exception{
		StringBuffer result = new StringBuffer();
		String resultMsg = "";
		String[] dealCodes = ids.split(",");  //交易流水号转换成数组
		String costStatuss = CimsConstant.COST_STATUS_DJ  +","+ CimsConstant.COST_STATUS_BH;  //结算状态为01-待结算,04-已驳回
		String creditSource = "02"; //来源：02-贷款
   	 	for(String dealCode : dealCodes){
	   	 	Map<String, Object>  param = new HashMap<String, Object>();
		 	param.put("dealCode", dealCode);//交易流水号
		 	param.put("creditSource", creditSource); //来源
		 	param.put("costStatuss", costStatuss); //结算状态为01-待结算,04-已驳回
			List<CreditDetailDto> list = dealService.getDealDetailListReturn(param);
			String applyCode = settleUtilsService.autoMakeSettleApplyCode(dealCode); //根据交易流水号自动生成结算编号
			logger.info("交易流水号="+dealCode+"，自动生成结算申请编号="+applyCode);
			if(CollectionUtils.isNotEmpty(list)){
				try {
					doLoanBuybackSettleSingle(dealCode, applyCode, null, list);
					resultMsg = "交易流水号=" + dealCode + "，结算申请编号=" + applyCode + "的结算申请处理成功!";
					result.append(resultMsg).append("\n\n");
					logger.info(resultMsg);
				} catch (Exception e) {
					resultMsg = "交易流水号=" + dealCode + "，结算申请编号=" + applyCode + "的结算申请处理失败！失败原因是：" +e.getMessage();
					result.append(resultMsg).append("\n\n");
					logger.error(resultMsg);
				}
			}else{
				resultMsg = "交易流水号：" + dealCode + "当前没有待结算记录!";
				result.append(resultMsg).append("\n\n");
				logger.error(resultMsg);
			}
   	 	}
   	 	return result.toString();
	}
	
	/**
	 * 处理贷款回购结算(单笔)
	 * @param dealCode 交易流水号
	 * @param applyCode 结算申请编号
	 * @param listCreditDetail
	 * @throws Exception
	 */
	public void doLoanBuybackSettleSingle(String dealCode, String applyCode, String frontTransNo, List<CreditDetailDto> listCreditDetail) throws Exception{
	    //第1步:公共结算参数定义
	    List<LoanBuybackSettleDto> loanBuybackSettleDtoList = new ArrayList<LoanBuybackSettleDto>();  //回购贷款列表
		List<LoanBuybackSettleCreditDto> loanBuybackSettleCreditDtoList = new ArrayList<LoanBuybackSettleCreditDto>();  //回购债权列表
		
		//第2步:准备封装公共结算参数-回购贷款loanBuybackSettleDto
	    logger.info("循环遍历所查询贷款信息，回购贷款列表size="+listCreditDetail.size());
	    for(CreditDetailDto creditDetailDto : listCreditDetail) {
		   LoanBuybackSettleDto loanBuybackSettleDto = new LoanBuybackSettleDto();
		   loanBuybackSettleDto.setBatchId(dealCode);  //交易流水号
		   loanBuybackSettleDto.setContractNo(creditDetailDto.getCreditCode());  //合同号
		   loanBuybackSettleDto.setBuybackContractValue(creditDetailDto.getDealMakeCreditorValue());   //回购贷款金额
		   loanBuybackSettleDto.setBuybackCreditValue(creditDetailDto.getBackMatchValue());  //回购债权金额
		   loanBuybackSettleDto.setServiceCharge(BigDecimal.ZERO);  //服务费,预留字段(暂无)
		   loanBuybackSettleDto.setCashDeposit(BigDecimal.ZERO);    //保证金,预留字段(暂无)
		   loanBuybackSettleDto.setGuaranteeFee(BigDecimal.ZERO);   //担保费,预留字段(暂无)
		   loanBuybackSettleDtoList.add(loanBuybackSettleDto);
	   }
	    
	   //第3步:准备封装公共结算参数-回购债权loanBuybackSettleCreditDto
	   TCMmDealMatchDTO dealMatchDto = new TCMmDealMatchDTO();
	   dealMatchDto.setBackLoanDealCode(dealCode);  //回购交易流水号
	   dealMatchDto.setValidateState(CimsConstant.DATE_STATUS_VALID); //数据有效性1-有效
	   Map<String, Object> searchParams = new HashMap<String, Object>();
	   searchParams.put("dto", dealMatchDto);
	   List<TCMmDealMatchDTO> tCMmDealMatchDTOList = tCMmDealMatchDao.searchTCMmDealMatch(searchParams);
	   if(CollectionUtils.isNotEmpty(tCMmDealMatchDTOList)){
		   logger.info("循环遍历所查询贷款回购匹配债权信息，交易流水号="+dealCode +"，回购债权列表size="+tCMmDealMatchDTOList.size());
		   for(TCMmDealMatchDTO dto:tCMmDealMatchDTOList){
			   LoanBuybackSettleCreditDto loanBuybackSettleCreditDto = new LoanBuybackSettleCreditDto();
			   loanBuybackSettleCreditDto.setBatchId(dto.getDealCode());  //赎回确认批次号
			   loanBuybackSettleCreditDto.setTransferId(dto.getTransferId());      //债权转让编号
			   loanBuybackSettleCreditDtoList.add(loanBuybackSettleCreditDto);
		   }
	   }
	   
	    String userId = String.valueOf(sessionAPI.getCurrentUserInfo().getUserId());  //用户ID
	    String cCode = listCreditDetail.get(0).getCooperorgCode();   //合作机构代码
	    String applyName = sessionAPI.getCurrentUserInfo().getUserName();  //用户姓名
	    
	    //第4步:调用接口
	    logger.info("准备调用贷款回购结算申请接口，交易流水号="+dealCode+"，结算申请编号="+applyCode);
	    callInterface4049(dealCode, applyCode, frontTransNo, cCode, applyName, userId, listCreditDetail, loanBuybackSettleDtoList, loanBuybackSettleCreditDtoList);
	}
	
	
	/**
	 * @param dealCode
	 * @param applyCode
	 * @param frontTransNo
	 * @param cCode
	 * @param applyName
	 * @param userId
	 * @param listCreditDetail
	 * @param loanBuybackSettleDtoList
	 * @param loanBuybackSettleCreditDtoList
	 * @return
	 * @throws Exception 
	 */
	public void callInterface4049(String dealCode, String applyCode, String frontTransNo, String cCode, String applyName, String userId,
			List<CreditDetailDto> listCreditDetail,
			List<LoanBuybackSettleDto> loanBuybackSettleDtoList, 
			List<LoanBuybackSettleCreditDto> loanBuybackSettleCreditDtoList) throws Exception{
	   if (frontTransNo == null) {
		   frontTransNo = iInteractAssist.getBusiNoForInteract();
	   } 
	   if(CollectionUtils.isNotEmpty(loanBuybackSettleDtoList)){
		   //第5步:公共结算参数组装
		   PublicSettleParamDto publicSettleParamDto = new PublicSettleParamDto();
		   publicSettleParamDto.setFrontTransNo(frontTransNo);  //前置交易系统流水号
		   publicSettleParamDto.setDealCode(dealCode);    //交易流水号
		   publicSettleParamDto.setApplyCode(applyCode);  //结算申请编号
		   publicSettleParamDto.setCCode(cCode);   //合作机构代码
		   publicSettleParamDto.setLoanBuybackSettleDtoList(loanBuybackSettleDtoList);  //回购贷款列表
		   publicSettleParamDto.setLoanBuybackSettleCreditDtoList(loanBuybackSettleCreditDtoList);  //回购债权列表
		   publicSettleParamDto.setApplyName(applyName);  //申请人姓名
		   
		   //第6步:调用接口:发送贷款回购结算申请
		   try {
				logger.error(">>>>>>>>>>调用贷款回购结算申请接口4049开始：frontTransNo=" + frontTransNo);
				PublicSettleResultDto resultDto = iCInteract.sendLoanBuybackSettleApply(publicSettleParamDto);
				logger.error(">>>>>>>>>>调用贷款回购结算申请接口4049成功：frontTransNo=" + frontTransNo );
				
				//成功后更新结算状态
				if(resultDto.isSuccess() && resultDto.getRetCode().equals("0000")){
					if(CollectionUtils.isNotEmpty(loanBuybackSettleDtoList)){
						logger.info("更新交易流水明细表(贷款)结算状态,结算申请编号,最后更新人,最后更新时间");
						updateLoanBuybackSettleCostState(dealCode, applyCode, loanBuybackSettleDtoList); 
					}
					//将来贷款回购结算部分贷款再加,结算全部贷款时不加
					/*if(CollectionUtils.isNotEmpty(loanBuybackSettleCreditDtoList)){
						logger.info("更新贷款回购匹配债权结算状态,结算申请编号,最后更新人,最后更新时间");
						updateLoanBuyBackCreditSettleCostState(dealCode, applyCode, loanBuybackSettleCreditDtoList);
					}*/
				}
			} catch (InteractException e) {
				logger.error(">>>>>>>>>>调用贷款回购结算申请接口4049失败：frontTransNo=" + frontTransNo);
				// 保存timeout记录表
				/*if(e.getMessage().contains(CimsExceptionConstant.INTERACT_NETWORK_ERROR)
						|| e.getMessage().contains(CimsExceptionConstant.INTERACT_SERVICE_FAIL+"业务处理中")){*/
				if(e.getMessage().contains(CimsExceptionConstant.INTERACT_NETWORK_ERROR)){
					for (CreditDetailDto creditDetailDto : listCreditDetail) {
				  		timeoutService.saveTimeoutRecord(creditDetailDto, frontTransNo, "4049", dealCode, userId);
				  	}
				}
				throw e;
			}
	   }
	}
	
	/**
	 * 更新交易流水明细表(贷款)结算状态
	 * @param dealCode 交易流水号
	 * @param applyCode 结算申请编号
	 * @param loanBuybackSettleDtoList 回购贷款列表
	 * @throws Exception
	 */
	public void updateLoanBuybackSettleCostState(String dealCode, String applyCode, List<LoanBuybackSettleDto> loanBuybackSettleDtoList) throws Exception{
		for (LoanBuybackSettleDto loanBuybackSettleDto : loanBuybackSettleDtoList) {
			TCMmCreditDealDetailDTO dto = new TCMmCreditDealDetailDTO();
			dto.setSettleApplyId(applyCode);   //结算申请编号
			dto.setCreditorId(loanBuybackSettleDto.getContractNo());  //合同编号
			dto.setCostState(CimsConstant.COST_STATUS_SQ);  //02-申请结算
			dto.setDealStreamCode(dealCode);   //交易流水号
			dto.setModifyBy(sessionAPI.getCurrentUserInfo().getLoginName()); //修改人登录名
			creditDealDetailDao.updateLoanBuybackDealDetailSettleApply(SearchParamUtil.getSearchParam(dto));
		}
	}
	
	/**
	 * 更新贷款回购匹配债权结算状态
	 * @param dealCode 交易流水号
	 * @param applyCode 结算申请编号
	 * @param loanBuybackSettleCreditDtoList 回购债权列表
	 * @throws Exception
	 */
	public void updateLoanBuyBackCreditSettleCostState(String dealCode, String applyCode, List<LoanBuybackSettleCreditDto> loanBuybackSettleCreditDtoList) throws Exception{
		for(LoanBuybackSettleCreditDto loanBuybackSettleCreditDto : loanBuybackSettleCreditDtoList){
			TCMmDealMatchDTO dto = new TCMmDealMatchDTO();
			dto.setBackLoanDealCode(dealCode);  //交易流水号(贷款回购)
			dto.setTransferId(loanBuybackSettleCreditDto.getTransferId());  //债权转让编号
			dto.setSettleId(applyCode); //结算申请编号
			dto.setSettleStatus(CimsConstant.COST_STATUS_SQ);  //02-申请结算
			dto.setModifyBy(sessionAPI.getCurrentUserInfo().getLoginName());  //修改人登录名
			creditDealDetailDao.updateLoanBuybackDetailCreditSettleApply(SearchParamUtil.getSearchParam(dto));
		}
	}
	
	/**
	 * 查询超时的流水号
	 * @param interfaceNo
	 * @return
	 */
	public List<String> queryTimeoutTransNos(String[] interfaceNo) {
		Map<String, Object> paramMap = new HashMap<String, Object>();
		paramMap.put("interfaceNos", interfaceNo);
		return timeoutDao.queryTimeoutTransNos(paramMap);
	}
}
